package com.project.class4_8.proxy2.service.impl;

import com.project.class4_8.proxy2.dao.impl.BaseDao;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;

public class ServiceProxy implements InvocationHandler {
    private Object targetObj;

    public ServiceProxy(Object targetObj) {
        this.targetObj = targetObj;
    }
    /**
     * 产生代理对象
     * @return 返回一个代理对象
     */
    public Object getProxy(){
        return Proxy.newProxyInstance(
                targetObj.getClass().getClassLoader(),
                targetObj.getClass().getInterfaces(),
                this
        );
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       //得到目标对象的属性列表
        Field[] fieldArray = targetObj.getClass().getDeclaredFields() ;
        //得到连接对象
        Connection con = BaseDao.getConnection();
        //设置提交方式为手动提交
        con.setAutoCommit(false);
        //遍历属性列表
        for (Field f : fieldArray){
            //去掉访问修饰符的检查
            f.setAccessible(true);
            //得到目标对象指定属性的值对象
            Object obj = f.get(targetObj);
            //判断属性是否为持久层组件
            if (obj instanceof BaseDao){
                BaseDao dao = (BaseDao) obj;
                //保证所有持久层组件一定是用的同一个连接（业务的要求）
                dao.setConnection(con);
            }
        }

        try {
            //执行目标对象中的目标方法
            Object returnObj = method.invoke(targetObj,args);

           //在所有方法执行完之后必须手动提交事务，否则数据库数据不会更新
            con.commit();
            return returnObj;
        }catch (Exception e){
            e.printStackTrace();
            //如果有异常完成事务的回滚
            con.rollback();
        }
        finally {
            //手动关闭连接
            con.close();
        }
        return null;
    }
}
